/**
 * X 兼容 Y ： X (目标类型) = Y (源类型)
 */

let s: string = 'a'
// Type 'null' is not assignable to type 'string'.
// 将 `tsconfig.json` 中的 `strictNullChecks` 设置为 false ，下面的就不会报错了。
// 但是运行还是报错 TS2322: Type 'null' is not assignable to type 'string'.

// s = null

/**
 * 接口兼容性
 */

interface X {
    a: any
    b: any
}

interface Y {
    a: any
    b: any
    c: any
}

let x: X = {a: 1, b: 2}
let y: Y = {a: 1, b: 2, c: 3}

x = y
// Property 'c' is missing in type 'X' but required in type 'Y'.
// y = x

/**
 * 函数兼容性
 */

type Handler = (a: number, b: number) => void
function hof(handler: Handler) {
    return handler
}

// 1) 参数个数

let handler1 = (a: number) => {}
hof(handler1)
let handler2 = (a: number, b: number, c: number) => {}
// Argument of type '(a: number, b: number, c: number) => void' is not assignable to parameter of type 'Handler'.
// hof(handler2)

// 可选参数和剩余参数
let a1 = (p1: number, p2: number) => {}
let b1 = (p1?: number, p2?: number) => {}
let c1 = (...args: number[]) => {}

a1 = b1
a1 = c1

// 以下两项打开，运行时，报错（chrome控制台）
// b1 = a1
// b1 = c1

c1 = a1
c1 = b1

// 2) 参数类型
let handler3 = (a: string) => {}
// Type 'number' is not assignable to type 'string'.
// hof(handler3)

interface Point3D {
    x: number
    y: number
    z: number
}
interface Point2D {
    x: number
    y: number
}
let p3d = (point: Point3D) => {}
let p2d = (point: Point2D) => {}

p3d = p2d
// Property 'z' is missing in type 'Point2D' but required in type 'Point3D'.
// p2d = p3d

// 3) 返回值类型

let f = () => ({name: 'Alice'})
let g = () => ({name: 'Alice', location: 'Beijing'})
f = g
// Property 'location' is missing in type '{ name: string; }' but required in type '{ name: string; location: string; }'.
// g = f

function overload(a: number, b: number): number
function overload(a: string, b: string): string
// Function implementation is missing or not immediately following the declaration. 如果没有紧挨着编写实现，会出现上面的错误提示
// function overload(a: any, b: any): any {}
// This overload signature is not compatible with its implementation signature. 如果实现中参数个数多了，会出现上面的错误提示
// function overload(a: any, b: any, c: any): any {}
// This overload signature is not compatible with its implementation signature. 如果没有定义返回类型，会出现上面的错误提示
// function overload(a: any, b: any) {}
function overload(a: any, b: any): any {}


// 枚举兼容性

enum Fruit { Apple, Banana }
enum Color { Red, Yellow }
let fruit: Fruit.Apple = 3
let num: number = Fruit.Apple
// Type 'Fruit.Apple' is not assignable to type 'Color.Red'.
// let color: Color.Red = Fruit.Apple


// 类兼容性


class A {
    constructor(p: number, q: number) {}
    id: number = 1
}
class B {
    static s = 1
    constructor(p: number) {}
    id: number = 2
}
let aa = new A(1, 2)
let bb = new B(1)
aa = bb
bb = aa

// 泛型兼容性

// 类兼容性和泛型兼容性，要看下文档，或重看视频来理解。

/**
 * 口诀：
 * 结构之间兼容： 成员少的兼容成员多的
 * 函数之间兼容： 参数多的兼容参数少的
 */



















